home *** CD-ROM | disk | FTP | other *** search
- /*
- Spinning Cursor Library
- Distributed by Philippe Casgrain
-
- What you need to know:
-
- 1) This library was taken directly and blatantly from the book "Macintosh
- Programming Secrets, Second Edition" (Addison-Wesley), and is distributed with
- the author's permission. You should get the book, because a) it's very
- informative and b) there are _lots_ of source code comments which I obviously
- didn't type in.
-
- 2) The library doesn't work by itself; you need to provide a resource file
- with two resources:
- - a 'CURS' resource, which is a list of all the cursor "frames" that you want
- to use in your animation. Note that if you want an animation that comes and
- goes (like the hand in the Apple Installer that first extends the fingers and
- then folds them back), you need to specify all the frames in order: the
- animation process goes one-way only.
- - an 'acur' resource, which specifies what are the "frames" ID numbers and the
- order you want them in.
- See the sample resource for an example.
-
- 3) There are three procedures you want to install in your program:
- - InitCursorCtl (acurResourceID: Integer);
- Use this routine once to initialize the cursor-animating task. The argument is
- the resource ID of the 'acur' resource, _not_ the 'CURS' resources: those are
- contained in the 'acur' resource.
-
- -StartAsyncSpinning (period: Integer);
- This starts the spinning cursor asynchronously (i.e. you can do other tasks
- while the cursor spins; it should not be affected). The argument is the delay
- (in ticks, or 1/60ths of second) between each cursor "frame". For instance, if
- you want to change the cursor each .25 second, set this value to 10.
-
- - StopAsyncSpinning;
- This stops the spinning cursor.
-
- 4) None of these tasks save the current cursor. You should do that yourself,
- and restore it afterwards.
-
-
- Other than that, share it and enjoy it!
-
- If you do use that library in anything that goes further than your desk, I
- would appreciate you telling me (I don't want a mention in your program, 'cause
- I only typed that code in!). Hey! a postcard would be real nice! But e-mail is
- fine (though I can't stick e-mail on my fridge and show it to my kids).
-
- Thanks to you all, out there on the 'net, and special thanks to Keith Rollin
- (and Scott Knaster) for de-mystifying Macintosh programming.
-
- Philippe Casgrain
- casgrain@ere.umontreal.ca
-
- 4 980 Boulevard Lalande
- Pierrefonds, Quebec
- Canada H8Y 1V8
-
- */
-
- #include "SpinningCursor.h"
- #include "Retrace.h"
-
- typedef struct {
- unsigned short numCursors;
- unsigned short index;
- CursHandle cursors[1];
- } Acur, *AcurPtr, **AcurHandle;
-
- typedef struct {
- VBLTask theTask;
- long A5;
- } VBLTaskWithA5, *VBLTaskWithA5Ptr;
-
- AcurHandle pCursors;
- VBLTaskWithA5Ptr pCursorTask;
- short pDesiredCount;
-
- char CrsrBusy : 0x08CD;
-
- void InitCursorCtl(short resID)
- {
- short cursorCount;
- CursHandle* workPtr;
-
- pCursors = (AcurHandle) GetResource('acur',resID);
-
- cursorCount = (**pCursors).numCursors;
- (**pCursors).numCursors *= 32;
- (**pCursors).index = 0;
-
- HLock((Handle) pCursors);
- workPtr = (**pCursors).cursors;
-
- while (cursorCount--) {
- *workPtr++ = (CursHandle) GetResource('CURS', *(short*) workPtr);
- }
- HUnlock((Handle) pCursors);
- }
-
- void SpinCursor(short increment)
- {
- short oldIndex;
- short newIndex;
-
- oldIndex = (**pCursors).index / 32;
-
- (**pCursors).index += increment;
- (**pCursors).index %= (**pCursors).numCursors;
-
- newIndex = (**pCursors).index / 32;
-
- if (newIndex != oldIndex) {
- SetCursor(*(**pCursors).cursors[newIndex]);
- }
- }
-
- void LockCursorData(void)
- {
- short cursorCount;
- CursHandle* workPtr;
-
- cursorCount = (**pCursors).numCursors / 32;
-
- HLockHi((Handle) pCursors);
- workPtr = (**pCursors).cursors;
- while (cursorCount--) {
- HLockHi((Handle) *workPtr++);
- }
- }
-
- void UnlockCursorData(void)
- {
- short cursorCount;
- CursHandle* workPtr;
-
- cursorCount = (**pCursors).numCursors / 32;
-
- workPtr = (**pCursors).cursors;
- while (cursorCount--) {
- HUnlock((Handle) *workPtr++);
- }
- HUnlock((Handle) pCursors);
- }
-
-
- void StartAsyncSpinning(short period)
- {
- LockCursorData();
-
- pDesiredCount = period;
-
- pCursorTask = (VBLTaskWithA5Ptr) NewPtr(sizeof(VBLTaskWithA5));
- pCursorTask->theTask.qType = vType;
- pCursorTask->theTask.vblAddr = (ProcPtr) MySpinner;
- pCursorTask->theTask.vblCount = pDesiredCount;
- pCursorTask->theTask.vblPhase = 0;
- pCursorTask->A5 = (long) CurrentA5;
-
- (void) VInstall((QElemPtr) pCursorTask);
- }
-
- void StopAsyncSpinning(void)
- {
- (void) VRemove((QElemPtr) pCursorTask);
- DisposePtr((Ptr) pCursorTask);
- UnlockCursorData();
- }
-
- void MySpinner(void)
- {
- long oldA5;
- VBLTaskWithA5Ptr myTaskPtr;
-
- asm {
- move.l A0, myTaskPtr
- }
-
- if (CrsrBusy == 0) {
- oldA5 = SetA5(myTaskPtr->A5);
- SpinCursor(32);
- myTaskPtr->theTask.vblCount = pDesiredCount;
- (void) SetA5(oldA5);
- }
- }
-